package com.ljx.designMode.factor;

/**
 * @author LJX
 * @Description: TODO
 * @Date: 2022/11/8 15:39
 * @Version 1.0
 * 开闭原则: 允许增加新的类，不允许修改原来类的代码。
 *
 * 工厂方法模式将工厂抽象化，并定义一个创建对象的接口。每增加新产品，
 * 只需增加该产品以及对应的具体实现工厂类，由具体工厂类决定要实例化的产品是哪个，
 * 将对象的创建与实例化延迟到子类，这样工厂的设计就符合“开闭原则”了，
 * 扩展时不必去修改原来的代码==。在使用时，用于只需知道产品对应的具体工厂，
 * 关注具体的创建过程，甚至不需要知道具体产品类的类名，当我们选择哪个具体工厂时，
 * 就已经决定了实际创建的产品是哪个了。
 * 但缺点在于，每增加一个产品都需要增加一个具体产品类和实现工厂类，
 * 使得系统中类的个数成倍增加，在一定程度上增加了系统的复杂度，同时也增加了系统具体类的依赖
 * 缺点: 增加一个新的产品， 需要创建一个新产品的类，以及新产品的工厂类。
 * 随着产品的不断增加，那么类也会成倍增加。
 */
public class FactoryMethod {
	public static void main(String[] args) {

		HuaWeiFactory huaWeiFactory = new HuaWeiFactory();
		// 通过华为工厂创建华为手机对象
		Phone phone = huaWeiFactory.createPhone();
		// 调用手机开始运行
		phone.callPhone();

		XiaomiFactory xiaomiFactory=new XiaomiFactory();
		Phone phone1 = xiaomiFactory.createPhone();
		phone1.callPhone();
	}
}

/**
 * 抽象产品 AbstractProduct：是具体产品继承的父类或实现的接口，
 * 在 Java 中一般有抽象类或者接口来实现。
 */
abstract class Phone{
	public abstract void callPhone();
}

/**
 * 具体产品 Product：具体工厂角色所创建的对象就是此角色的实例。
 */
class XiaoMi extends Phone{
	@Override
	public void callPhone() {
		System.out.println("小米手机打电话");
	}
}

class HuaWei extends Phone{
	@Override
	public void callPhone() {
		System.out.println("华为手机打电话");
	}
}

/**
 * 抽象工厂 AbstractFactory： 工厂方法模式的核心，
 * 是具体工厂角色必须实现的接口或者必须继承的父类，
 * 在 Java 中它由抽象类或者接口来实现
 */
interface PhoneFactory{
   	 public  Phone createPhone();
}

/**
 * 具体工厂 Factory：被应用程序调用以创建具体产品的对象，含有和具体业务逻辑有关的代码
 */
class XiaomiFactory implements PhoneFactory{
	@Override
	public Phone createPhone() {
		return new XiaoMi();
	}
}

class HuaWeiFactory implements PhoneFactory{
	@Override
	public Phone createPhone() {
		return new HuaWei();
	}
}
